const fs = require("fs");
const xml2js = require("xml2js");

var xmlParser = new xml2js.Parser({ explicitArray: false, ignoreAttrs: true });

module.exports = class gcfg2json {
  constructor(input_path = "./gcfg", output_path = "./json") {
    this.input_path = input_path;
    this.output_path = output_path;

    var filelist = this.walk(this.input_path);

    for (let filepath of filelist) {
      fs.readFile(filepath, (err, data) => {
        if (err) return console.error(err);
        this.onread(data, this.getfilename(filepath));
      });
    }
  }
  walk(dir) {
    var results = [];
    var list = fs.readdirSync(dir);
    list.forEach(file => {
      file = dir + "/" + file;
      var stat = fs.statSync(file);
      if (stat && stat.isDirectory()) results = results.concat(this.walk(file));
      else results.push(file);
    });
    return results;
  }

  onread(data, filename) {
    var xml = data.toString();
    xmlParser.parseString(xml, (err, result) => {
      if (err) return console.error(err);
      this.onparse(result, filename);
    });
  }

  onparse(result, filename) {
    var old_obj = result;
    var new_obj = {
      files: [],
      explain: old_obj.Config.Readme,
      title: filename
    };

    var files_map = {};

    if (!(old_obj.Config.Files.File instanceof Array))
      old_obj.Config.Files.File = [old_obj.Config.Files.File];
    for (const setting of old_obj.Config.Files.File) {
      if (!(files_map[setting.name] instanceof Array))
        files_map[setting.name] = [];
      files_map[setting.name].push(setting);
    }

    for (const key of Object.keys(files_map)) {
      let file = {
        file: key,
        data: []
      };
      for (const setting of files_map[key]) {
        file.data.push({
          address: setting.addr,
          revise: setting.surrenal,
          restore: setting.restore || setting.surrenal
        });
      }
      new_obj.files.push(file);
    }

    this.write(JSON.stringify(new_obj), filename);
  }

  write(json, filename) {
    fs.writeFile(
      this.output_path + "/" + filename + ".json",
      json,
      { flag: "w" },
      err => {
        if (err) return console.error(err);
      }
    );
  }

  getfilename(filepath) {
    let patharr = filepath.split("/");
    let filenamearr = patharr[patharr.length - 1].split(".");
    return filenamearr[filenamearr.length - 2];
  }
};
